package com.yyge.controller.admin.sysdicttype;

import com.alibaba.excel.EasyExcel;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.yyge.common.controller.BaseController;
import com.yyge.common.enums.AckCode;
import com.yyge.common.vo.req.PageReq;
import com.yyge.common.vo.resp.PageResp;
import com.yyge.controller.admin.mapstruct.SysDictDataConverter;
import com.yyge.controller.admin.sysdicttype.req.SysDictTypeEditReq;
import com.yyge.controller.admin.sysdicttype.req.SysDictTypeReq;
import com.yyge.controller.admin.mapstruct.SysDictTypeConverter;
import com.yyge.controller.admin.sysdicttype.resp.SysDictTypeResp;
import com.yyge.entity.SysDictData;
import com.yyge.entity.SysDictType;
import com.yyge.service.SysDictDataService;
import com.yyge.service.SysDictTypeService;
import com.yyge.common.vo.resp.R;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.yyge.util.DicUtil;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.*;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.bind.annotation.RequestMapping;

import javax.crypto.spec.PSource;
import javax.servlet.http.HttpServletResponse;
import javax.validation.Valid;
import java.io.IOException;
import java.net.URLEncoder;
import java.net.URLPermission;
import java.util.*;

@Api(tags = "后台管理 - 数据字典")
@RestController
@RequestMapping("/api/sysdicttype")
public class SysDictTypeController extends BaseController<SysDictType,Object> {
    public SysDictTypeController (){
        this.converter=SysDictDataConverter.class;
    }
    // 注入业务逻辑层
    private SysDictTypeService service;

    @Autowired
    private DicUtil dicUtil;

    @Autowired
    private SysDictDataService sysDictDataService;

    @Autowired/*自动装配*/
    public void setService(SysDictTypeService sysdicttypeService){
        this.service=sysdicttypeService;
    }

    @GetMapping("data")/* GET(SELECT): 查询 */
    @ApiOperation(value = "分页查询")
    public R<PageResp<SysDictTypeResp>> getType(SysDictTypeReq req) throws Exception  {
        QueryWrapper queryWrapper = this.getWrapper(req);
        PageResp<SysDictTypeResp> pageResp =this.page(req,pageInfo ->service.page(pageInfo,queryWrapper));
        return R.okHasData(pageResp);
    }

    @GetMapping("data/all")/* GET(SELECT): 查询 */
    @ApiOperation(value = "分页查询")
    public R<PageResp<SysDictType>> getDataAll(PageReq<SysDictType> vo,SysDictTypeReq req) throws Exception  {

        List<SysDictType> list = service.list();
        PageResp pageResp=new PageResp<>();
        pageResp.setRows(list);
        pageResp.setPageSize(list.size());
        pageResp.setTotal(1L);
        pageResp.setPageNum(1);

        return R.okHasData(pageResp);
    }

    @GetMapping("/{id}")/* GET(SELECT): 查询 */
    @ApiOperation(value = "分页查询-根据ID查数据")
    public R get(SysDictTypeReq req) throws Exception  {

        // 将对象进行转换过滤无效条件
        if(Objects.isNull(req.getDictType())){

        }
        SysDictType byId = service.getById(req.getId());

        SysDictTypeResp sysDictTypeResp = SysDictTypeConverter.MAPPER.convert(byId);
        return R.okHasData(sysDictTypeResp);
    }

    @PostMapping/* POST(CREATE): 新增&登陆 */
    public R post(@RequestBody SysDictType sysdicttype){
        Boolean i=service.save(sysdicttype);
        return i?R.ok("新增成功！"):R.error(AckCode.SYSTEM_SERVICE_ADD_ERROR);
    }

    @PutMapping/* POST(CREATE): 更新 */
    @Transactional
    public R out(@RequestBody @Valid SysDictTypeEditReq req){
        /**
         * intValue()方法要加@Vallid注解才能使用
         * SysDictType的更新策略
         * 1.先用SysDictTypeEditReq对象进行自动接收
         * 2.根据SysDictTypeEditReq的ID,根据ID获取到SysDictType数据库中的对象
         * 3.直接先更新SysDictType
         * 4.判断SysDictTypeEditReq与查出的SysDictType的sysDictType值是否一致
         * 5.如果不一致则更新SysDictData中的对象DictType的值
         * 6.加上事务,要么同时成功！要么同时失败...
         */
        //确保id>0
        if(req.getId().intValue()<0){
         return R.build(AckCode.SYSTEM_PARAM_FAIL);
        }

        SysDictType db = service.getById(req.getId());
        if(Objects.isNull(db)){
            return R.build(AckCode.DATA_NOT_FOUND);
        }

        SysDictType sysDictType = SysDictTypeConverter.MAPPER.convert(req);
        boolean save=service.updateById(sysDictType);
        boolean update=false;
        //判断，如果是修改了dictType的值，就必须要更新sysDictData表的数据
        if(!req.getDictType().equals(db.getDictType())){
            LambdaUpdateWrapper<SysDictData> updateWrapper=new LambdaUpdateWrapper<>();
            updateWrapper.eq(SysDictData::getDictType,db.getDictType());
            updateWrapper.set(SysDictData::getDictType,req.getDictType());
            update = sysDictDataService.update(null,updateWrapper);
            //清空以前的redis缓存，因为你的dict_type的值已经被改过了
            dicUtil.removeByDictType(db.getDictType());
        }else{
            if(save){update=true;}
        }

        //如果是禁用状态，就要移出redis缓存中的值
        if(db.getStatus().equals("1")){
            dicUtil.removeByDictType(req.getDictType());
        }else{
            if(!req.getDictType().equals(db.getDictType())){
                dicUtil.refreshCacheByDictType(req.getDictType());
            }else{
                dicUtil.refreshCacheByDictType(db.getDictType());
            }
        }
        if(save!=true || update!=true){
            update=false;
        }
        return update?R.ok("修改成功！"):R.error(AckCode.SYSTEM_SERVICE_MODIFY_ERROR);
    }

    @PatchMapping/* PUT(UPDATE): 部分更新 */
    public R patch(@RequestBody SysDictType sysdicttype){
        return null;
    }

    @DeleteMapping/* DELETE(DELETE): 删除&&批量删除 */
    public R delete( Integer[] ids){
        System.out.println(ids);
        //boolean i = service.removeByIds(Arrays.asList(list));
        boolean i=false;
        return i?R.ok("修改成功！"):R.error(AckCode.SYSTEM_SERVICE_DELETE_ERROR);
    }

    @ApiOperation(value = "刷新缓存")
    @PostMapping(value = "/refresh")
    public R freshRedisCache(){
        System.out.println("正在刷新缓存.......");
        this.dicUtil.removeAllRedisDictData();
        this.dicUtil.loadAllDictDataToRedis();
        return R.ok();
    }


    @ApiOperation(value = "excel下载")
    @PostMapping(value = "/download")
    public void download(HttpServletResponse response, @RequestBody  SysDictTypeReq req) throws IOException {
        System.out.println(req);
        List<SysDictType> arrList=this.service.download(req);
        List<SysDictTypeResp> convert = SysDictTypeConverter.MAPPER.convert(arrList);
        // 这里注意 有同学反应使用swagger 会导致各种问题，请直接用浏览器或者用postman
        response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
        response.setCharacterEncoding("utf-8");
        // 这里URLEncoder.encode可以防止中文乱码 当然和easyexcel没有关系
        String fileName = URLEncoder.encode("data", "UTF-8").replaceAll("\\+", "%20");
        response.setHeader("Content-disposition", "attachment;filename*=utf-8''" + fileName + ".xlsx");
        EasyExcel.write(response.getOutputStream(), SysDictTypeResp.class).sheet("数据").doWrite(convert);
    }

}

